﻿using System;
using System.Text;

namespace Zjh.PackSerializer.Utils
{
    public class BinaryUtil
    {
        /// <summary>
        /// 16进制字符串转字节数组
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        public static byte[] HexStringToBinary(string hexString)
        {
            byte[] buffer = new byte[hexString.Length / 2];
            for (int i = 0; i < buffer.Length; i++)
            {
                var byteStr = hexString.Substring(i * 2, 2);
                buffer[i] = Convert.ToByte(byteStr, 16);
            }
            return buffer;
        }
        public static void ConsolePrintFormat(byte[] buffer)
        {
            var hexString = BinaryToHexStringFormat(buffer);
            if (!string.IsNullOrEmpty(hexString))
                Console.WriteLine(hexString);
        }

        public static void ConsolePrint(byte[] buffer)
        {
            var hexString = BinaryToHexString(buffer);
            if (!string.IsNullOrEmpty(hexString))
            {
                Console.WriteLine(hexString);
            }
        }

        /// <summary>
        /// 字节数组转16进制字符串
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="split"></param>
        /// <returns></returns>
        public static string BinaryToHexString(byte[] buffer, char? split = ' ')
        {
            if (buffer == null)
                return string.Empty;
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < buffer.Length; i++)
            {
                builder.Append(buffer[i].ToString("X2"));
                if (split != null)
                {
                    builder.Append(split);
                }
            }
            if (split != null)
            {
                builder.ToString().Trim(new char[] { (char)split });
            }
            return builder.ToString();
        }

        public static string TimeFormatString = "yyyy-MM-dd HH:mm:ss.fff";

        /// <summary>
        /// 字节数组转16进制字符串（带格式）
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public static string BinaryToHexStringFormat(byte[] buffer)
        {
            /*
             * ----------------------------------------------------------------------------
             * - TIME: 2019-10-16 15:33:50.000
             * ----------------------------------------------------------------------------
             *            |  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F |
             * -----------+----------------------------------------------+-----------------
             * 0x00000000 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
             * 0x00000010 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
             */
            if (buffer == null)
                return string.Empty;
            StringBuilder builder = new StringBuilder();
            builder.AppendLine("-------------------------------------------------------------------------------");
            builder.AppendLine($"- TIME: {DateTime.Now.ToString(TimeFormatString)}");
            builder.AppendLine("-----------+-------------------------------------------------+-----------------");
            builder.AppendLine("           |  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F |");
            builder.AppendLine("-----------+-------------------------------------------------+-----------------");
            for (int i = 0; i < buffer.Length; i += 0x10)
            {
                builder.Append($"0x{i.ToString("X8")} |");
                for (int j = 0; j < 0x10; j++)
                {
                    if (i + j >= buffer.Length)
                    {
                        builder.Append("   ");
                        continue;
                    }
                    builder.Append($" {buffer[i + j].ToString("X2")}");
                }
                builder.Append(" | ");
                for (int j = 0; j < 0x10 && i + j < buffer.Length; j++)
                {
                    var b = buffer[i + j];
                    if (b >= 0x20 && b <= 0x7F)
                    {
                        builder.Append(Convert.ToChar(b));
                    }
                    else
                    {
                        builder.Append(".");
                    }
                }
                builder.AppendLine();
            }
            return builder.ToString();
        }
    }
}